﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pibby.Core
{

	public class EpisodeClassifier : IClassifyEpisodes
	{
		#region Constructors

		public EpisodeClassifier(DateTime dt)
		{
			this.Date = dt;

			this.BackCatalogThreshold = 30;
			this.RecentThreshold = 7;
			this.NewThreshold = 1;
		}

		#endregion Constructors

		#region Properties
		
		public DateTime Date
		{
			get;
			set;
		}

		public int BackCatalogThreshold
		{
			get;
			set;
		}

		public int RecentThreshold
		{
			get;
			set;
		}

		public int NewThreshold
		{
			get;
			set;
		}

		#endregion Properties

		#region Methods

		public EpisodeAge Classify(IEpisode episode)
		{
			if (episode == null)
			{
				throw new ArgumentNullException("episode", Resources.Episode_NullObjectError);
			}

			EpisodeAge age = this.Classify(episode.PublicationDate);

			episode.Age = age;

			return age;
		}

		public EpisodeAge Classify(DateTime publicationDate)
		{
			EpisodeAge age = EpisodeAge.Unknown;

			TimeSpan sinceLastUpdate = publicationDate - this.Date;

			if (sinceLastUpdate.TotalDays >= 0)
			{
				// published since our given date
				age = EpisodeAge.BrandNew;

				TimeSpan sinceToday = DateTime.Today - publicationDate;

				if (sinceToday.TotalDays >= this.BackCatalogThreshold)
				{
					age = EpisodeAge.BackCatalog;
				}
				else if (sinceToday.TotalDays >= this.RecentThreshold)
				{
					age = EpisodeAge.Recent;
				}
				else
				{
					if (sinceToday.TotalDays >= this.NewThreshold)
					{
						age = EpisodeAge.Newish;
					}
					else
					{
						age = EpisodeAge.BrandNew;
					}
				}
			}
			else
			{
				int daysAgo = (int)Math.Abs(Math.Floor(sinceLastUpdate.TotalDays));

				// published some time before our given date...
				if (daysAgo >= this.BackCatalogThreshold)
				{
					age = EpisodeAge.BackCatalog;
				}
				else if (daysAgo >= this.RecentThreshold)
				{
					age = EpisodeAge.Recent;
				}
				else
				{
					if (daysAgo >= this.NewThreshold)
					{
						age = EpisodeAge.Newish;
					}
					else
					{
						age = EpisodeAge.BrandNew;
					}
				}
			}

			return age;
		}

		#endregion Methods
	}
}
